package com.panda.crud.logic.delete.auto.fill.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.panda.crud.logic.delete.auto.fill.dao.UserMapper;
import com.panda.crud.logic.delete.auto.fill.entity.Result;
import com.panda.crud.logic.delete.auto.fill.entity.User;
import com.panda.crud.logic.delete.auto.fill.entity.UserQuery;
import com.panda.crud.logic.delete.auto.fill.service.UserService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public List<User> queryUserList(UserQuery query) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        // id = 1
        queryWrapper.eq(Objects.nonNull(query.getId()), User::getId, query.getId())
                // gender <> 1
                .ne(Objects.nonNull(query.getGender()), User::getGender, query.getGender())
                // tenant_id in ('00001', '00002', '00003')
                .in(CollectionUtils.isNotEmpty(query.getTenantIds()), User::getTenantId, query.getTenantIds())
                // not in ('00001', '00002', '00003')
                .notIn(CollectionUtils.isNotEmpty(query.getTenantIds()), User::getTenantId, query.getTenantIds())
                // age > 22
                .gt(Objects.nonNull(query.getAge()), User::getAge, query.getAge())
                // age >= 22
                .ge(Objects.nonNull(query.getAge()), User::getAge, query.getAge())
                // age < 100
                .lt(Objects.nonNull(query.getAge()), User::getAge, query.getAge())
                // age <= 100
                .le(Objects.nonNull(query.getAge()), User::getAge, query.getAge())
                // name like '%伟%'
                .like(StringUtils.isNotBlank(query.getName()), User::getName, query.getName())
                // name not like '%伟%'
                .notLike(StringUtils.isNotBlank(query.getName()), User::getName, query.getName())
                // name like '%伟'
                .likeLeft(StringUtils.isNotBlank(query.getName()), User::getName, query.getName())
                // name like '王%'
                .likeRight(StringUtils.isNotBlank(query.getName()), User::getName, query.getName())
                // create_time between '2011-11-11 11:11:11' and '2023-11-11 11:11:11'
                .between(Objects.nonNull(query.getCreateTime()), User::getCreateTime, query.getBeginTime(), query.getEndTime())
                // create_time not between '2011-11-11 11:11:11' and '2023-11-11 11:11:11'
                .notBetween(Objects.nonNull(query.getCreateTime()), User::getCreateTime, query.getBeginTime(), query.getEndTime())
                // and exists (select * from tbl_tenant where enable = 1 and deleted = 0)
                .exists(Objects.nonNull(query.getDeleted()), "select * from tbl_tenant where enable = {0} and deleted = {1}", 1, 0)
                // and not exists (select * from tbl_tenant where enable = 1)
                .notExists(Objects.nonNull(query.getDeleted()), "select * from tbl_tenant where enable = {0} and deleted = {1}", 1, 0)
                // address IS NULL
                .isNull(true, User::getAddress)
                // address IS NOT NULL
                .isNotNull(StringUtils.isNotBlank(query.getAddress()), User::getAddress)
                // group by deleted, enable
                .groupBy(true, User::getDeleted, User::getEnable)
                // order by id asc
                .orderByAsc(true, User::getId)
                // order by update_time desc
                .orderByDesc(true, User::getUpdateTime)
                .last(true, "limit 10");

        return getBaseMapper().selectList(queryWrapper);
    }

    @Override
    public User queryUser(Long id) {
        return getBaseMapper().selectById(id);
    }

    @Override
    public Boolean addUser(User user) {
//        return this.save(user);
        return getBaseMapper().insert(user) > 0;
    }

    @Override
    public Boolean addUsers(List<User> users) {
        return this.saveBatch(users, 500);
    }

    @Override
    public Boolean saveOrUpdateBatch(List<User> users) {
        return this.saveOrUpdateBatch(users, 500);
    }

    @Override
    public Boolean updateUserById(User user) {
        User user1 = getBaseMapper().selectById(user.getId());
        User user2 = getBaseMapper().selectById(user.getId());

        user1.setNickName("乐观锁");
        getBaseMapper().updateById(user1);

        user2.setNickName("乐观锁呀");
        getBaseMapper().updateById(user2);

        return true;
    }

    @Override
    public Boolean updateUser(User user) {
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id_card", user.getIdCard());
        return getBaseMapper().update(user, updateWrapper) > 0;
    }

    @Override
    public Boolean updateBatchById(List<User> users) {
        return this.updateBatchById(users, 500);
    }

    @Override
    public Boolean deleteById(Long id) {
//        return this.removeById(id);
        return getBaseMapper().deleteById(id) > 0;
    }

    @Override
    public Boolean deleteUserByIds(List<Long> ids) {
//        return this.removeBatchByIds(ids, 500);
        return getBaseMapper().deleteBatchIds(ids) > 0;
    }

    @Override
    public Boolean deleteUserById(User user) {
//        return this.removeById(user);
        return getBaseMapper().deleteById(user) > 0;
    }

    @Override
    public Boolean deleteUser(User user) {
        UpdateWrapper<User> deleteWrapper = new UpdateWrapper<>();
        deleteWrapper.eq("id_card", user.getIdCard());
        deleteWrapper.eq("deleted", user.getDeleted());

//        return this.remove(deleteWrapper);
        return getBaseMapper().delete(deleteWrapper) > 0;
    }

    @Override
    public Result<Page<User>> pageUsers(UserQuery userQuery) {
        Page<User> page = new Page<>(userQuery.getPageNum(), userQuery.getPageSize());
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        return Result.success(getBaseMapper().selectPage(page, queryWrapper));
    }

    @Override
    public User queryByUserId(Long userId) {
        return getBaseMapper().selectUserById(userId);
    }

    @Override
    public Boolean updateAllTable() {
        User user = new User();
        user.setNickName("全表更新");
        return getBaseMapper().update(user, null) > 0;
    }

    @Override
    public Boolean deleteAllTable() {
        return getBaseMapper().delete(null) > 0;
    }

    @Override
    public List<User> getUserByTableName(UserQuery userQuery) {
        return getBaseMapper().getUserByTableName(userQuery);
    }
}
